﻿using ProductSystem.BLL.Common;
using ProductSystem.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace ProductSystem.Web.Controllers
{
    /// <summary>
    /// 后台身份验证
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class ManageAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {
        private bool requireSystemAdministrator = false;
        /// <summary>
        /// 是否需要系统管理员权限
        /// </summary>
        public bool RequireSystemAdministrator
        {
            get { return requireSystemAdministrator; }
            set { requireSystemAdministrator = value; }
        }

        private bool requireCheckRole = false;
        public bool RequireCheckRole
        {
            get { return requireCheckRole; }
            set { requireCheckRole = value; }
        }

        private string actionName = string.Empty;
        public String ActionName
        {
            get { return actionName; }
            set { actionName = value; }

        }

        private bool noFunction = false;

        #region IAuthorizationFilter 成员

        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            string returnUrl = string.Empty;
            if (filterContext.HttpContext.Request.UrlReferrer != null)
            {
                returnUrl = filterContext.HttpContext.Request.Url.PathAndQuery.ToString();
            }


            ReflectedActionDescriptor actionDesc = filterContext.ActionDescriptor as ReflectedActionDescriptor;
            var actionReturnType = actionDesc.MethodInfo.ReturnType.Name;

            String urlhost = filterContext.RequestContext.HttpContext.Request.ServerVariables["HTTP_HOST"];

            //LogHelper.Instance().WriteLog("String port =" + urlhost);  


            if (!AuthorizeCore(filterContext))
            {
                switch (actionReturnType)
                {
                    case "ActionResult":
                        {
                            AppUserSession.Instance().SetReturnUrl(returnUrl);
                            if (string.IsNullOrEmpty(returnUrl.Trim()))
                            {
                                var destinationUrl = String.Format("http://{0}{1}", urlhost,
                                    TBConfig.Instance().ManageLoginUrl());
                                //LogHelper.Instance().WriteLog("String destinationUrl =" + destinationUrl);  

                                filterContext.Result = new RedirectResult(destinationUrl);
                            }
                            else
                            {

                                var destinationUrl = String.Format("http://{0}{1}", urlhost,
                                    TBConfig.Instance().ManageTimeOutUrl());
                                filterContext.Result = new RedirectResult(destinationUrl);

                            }
                        }

                        break;
                    case "JsonResult":
                        JsonResult jsonResult = new JsonResult();
                        jsonResult.Data = new { AjaxResultCode = false, ReturnUrl = TBConfig.Instance().ManageLoginUrl() };
                        filterContext.Result = jsonResult;
                        break;
                    default:
                        break;

                }
                // auth failed, redirect to login page 
            }
            else
            {
                if (!CheckUserFunction(filterContext))
                {
                    switch (actionReturnType)
                    {
                        case "ActionResult":
                            AppUserSession.Instance().SetReturnUrl(returnUrl);
                            filterContext.Result = new RedirectResult(TBConfig.Instance().ManageNoRoleUrl() + "?str=1");
                            break;
                        case "JsonResult":
                            JsonResult jsonResult = new JsonResult();
                            jsonResult.Data = new { AjaxResultCode = false, ReturnUrl = TBConfig.Instance().ManageNoRoleUrl() + "?str=1" };
                            filterContext.Result = jsonResult;
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        #endregion

        // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
        protected virtual bool AuthorizeCore(AuthorizationContext filterContext)
        {
            LoginUser currentUser = AppUserSession.Instance().GetCurrentUser();
            if (currentUser != null)
            {
                LogUserAction(filterContext, currentUser);
                return true;
            }

            //行为记录
            return false;
        }
        /// <summary>
        /// 检查权限
        /// </summary>
        /// <param name="filterContext"></param>
        /// <returns></returns>
        protected virtual bool CheckUserFunction(AuthorizationContext filterContext)
        {
            LoginUser currentUser = AppUserSession.Instance().GetCurrentUser();
            string checkAction = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName + "-" + filterContext.ActionDescriptor.ActionName;
            //检查用户有权限菜单
            bool Result = AuthenticationService.Instance().CheckUserFunction(currentUser.UserId, checkAction);

            if (String.IsNullOrEmpty(actionName))
                actionName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName + "-" + filterContext.ActionDescriptor.ActionName;

            if (requireCheckRole && !String.IsNullOrEmpty(ActionName))
            {
                return AuthenticationService.Instance().CheckUserFunction(currentUser.UserId, actionName);
            }
            else
            {
                return true;
            }
        }

        /// <summary>
        /// 防止表太大
        /// </summary>
        /// <param name="filterContext"></param>
        /// <param name="currentUser"></param>
        /// <returns></returns>
        private bool LogUserAction(AuthorizationContext filterContext, LoginUser currentUser)
        {
            try
            {
                //用户操作日志记录 匿名访问的Action 与 登录就可以访问的Action 不做记录
                var opLog = new System_UserActionLog()
                {
                    ControlerName = filterContext.RouteData.Values["controller"].ToString(),
                    ActionName = filterContext.RouteData.Values["action"].ToString(),
                    //UserID = currentUser.UserId,
                    UserName = currentUser.Account,
                    //ActionDesc = string.IsNullOrEmpty(filterContext.HttpContext.Request.QueryString.ToString()) ? "null" : "ActionParams:" + filterContext.HttpContext.Request.QueryString.ToString(),
                    CreateDate = DateTime.Now,
                    Url = filterContext.HttpContext.Request.Url == null ? "null" : filterContext.HttpContext.Request.Url.ToString(),
                    IPAddress = filterContext.HttpContext.Request.UserHostAddress,
                    FromUrl = filterContext.HttpContext.Request.UrlReferrer == null ? "null" : filterContext.HttpContext.Request.UrlReferrer.AbsoluteUri,
                    IsReceived = false
                };

                using (var entityModel = new EntitiesModel())
                {
                    entityModel.Add(opLog);
                    entityModel.SaveChanges();
                }
                return true;
            }
            catch (Exception e)
            {
                LogHelper.Instance().WriteLog("LogUserAction ERROR", e);
                return false;
            }
        }
    }
}